﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel;

using Bamboo.Helpers;
using Global.Helpers;
namespace Gama.Website
{
    public partial class VisitContext
    {
        public class CookieManager
        {
            private CookieManager() { }

            private static readonly CookieManager instance = new CookieManager();

            public static CookieManager Instance
            {
                get { return instance; }
            }

            public static HttpCookie GetCookieValue(string key)
            {
                if (HttpContext.Current.Request.Cookies[key] == null)
                {
                    return null;
                }

                return HttpContext.Current.Request.Cookies[key];
            }

            public static void SetCookieValue(string key, string value, DateTime? expiresWhen)
            {
                var cookie = new HttpCookie(key, value);

                if (expiresWhen.HasValue)
                {
                    cookie.Expires = expiresWhen.Value;
                };
                
                HttpContext.Current.Response.Cookies.Set(cookie);
            }

            private static void SetCookieValue(string key, string value, TimeSpan timeToLive)
            {
                SetCookieValue(key, value, DateTime.Now.Add(timeToLive));
            }

            private void SetCookieValue(string key, string value)
            {
                SetCookieValue(key, value, this.GetCookieTimeoutSetting(key));
            }

            private TimeSpan GetCookieTimeoutSetting(string propertyName)
            {
                var property = TypeDescriptor.GetProperties(this)
                                   .Cast<PropertyDescriptor>()
                                   .Where(p => p.Name == propertyName).SingleOrDefault();

                if (property != null)
                {
                    var expiration = property.Attributes.OfType<ExpireAttribute>().FirstOrDefault();

                    if (expiration != null)
                    {
                        return expiration.Timeout;
                    }
                }

                return TimeSpan.Zero;
            }

            public string SessionIdByCookie
            {
                get
                {
                    var sessionId = GetCookieValue("ASP.NET_SessionId");

                    return sessionId == null ? string.Empty : sessionId.Value;
                }
            }

            [Expire(GamaOptions.CookieTimeoutInDaysKey)]
            public Guid? GuestId
            {
                get
                {
                    Guid guestId;

                    var cookie = GetCookieValue(GamaOptions.GuestIdKey);

                    if (cookie == null || !Guid.TryParse(cookie.Value, out guestId))
                    {
                        return null;
                    }

                    return guestId;
                }
                set
                {
                    this.SetCookieValue(GamaOptions.GuestIdKey, value.ToStringEx());
                }
            }
            //[Expire(GamaOptions.CookieTimeoutInDaysKey)]
            public string Language
            {
                get
                {
                    var lang = GetCookieValue(GamaOptions.LanguageKey);
                    if (lang == null || lang.Value == null)
                    {
                        var langDefault = GamaOptions.LanguageDefault;
                        SetCookieValue(GamaOptions.LanguageKey, langDefault);
                        return langDefault;
                    }
                    return lang.Value;
                }
                set
                {
                    this.SetCookieValue(GamaOptions.LanguageKey, value);
                }
            }            
        }
        [AttributeUsage(AttributeTargets.Property)]
        internal class ExpireAttribute : Attribute
        {
            public ExpireAttribute(TimeSpan timeout)
            {
                this.Timeout = timeout;
            }

            public ExpireAttribute(string appSettingKey)
            {
                var reader = new System.Configuration.AppSettingsReader();

                object value = reader.GetValue(appSettingKey, typeof(int));

                if (value == null)
                {
                    throw new ArgumentException("AppSetting {0} could not be found.", appSettingKey);
                }

                var timeoutInDays = (int)value;

                this.Timeout = TimeSpan.FromDays(timeoutInDays);
            }

            public TimeSpan Timeout { get; private set; }
        }
    }
}